<?php
namespace Payment\Notify;


use Payment\Common\PayException;
use Payment\Common\UnionpayConfig;
use Payment\Config;
use Payment\Utils\ArrayUtil;

class UnionPayNotify extends NotifyStrategy
{
    /**
     * UnionpayConfig constructor.
     * @param array $config
     * @throws PayException
     */
    public function __construct(array $config)
    {
        parent::__construct($config);
        
        try {
            $this->config = new UnionpayConfig($config);
        } catch (PayException $e) {
            throw $e;
        }
    }

    /**
     * 获取移除通知的数据  并进行简单处理（如：格式化为数组）
     *
     * 如果获取数据失败，返回false
     *
     * @return array|boolean
     * @author helei
     */
    protected function getNotifyData()
    {
        $data = empty($_POST) ? $_GET : $_POST;
        if (empty($data) || !is_array($data)) {
            return false;
        }
       
        return $data;
    }

    /**
     * 检查异步通知的数据是否合法
     *
     * 如果检查失败，返回false
     *
     * @param array $data  由 $this->getNotifyData() 返回的数据
     * @return boolean
     * @author helei
     */
    protected function checkNotifyData(array $data)
    {
        // 检查签名
        $flag = $this->verifySign($data);
        if ($flag === false) {// 签名失败，直接返回
            return $flag;
        }else{
            return true;
        }
    }

    /**
     * 向客户端返回必要的数据
     * @param array $data 回调机构返回的回调通知数据
     * @return array|false
     * @author helei
     */
    protected function getRetData(array $data)
    {

        $retData = $this->getTradeData($data);

        return $retData;
    }


    /**
     *
    public 'accessType' => string '0' (length=1)
    public 'bizType' => string '000201' (length=6)
    public 'certId' => string '69597475696' (length=11)
    public 'currencyCode' => string '156' (length=3)
    public 'encoding' => string 'utf-8' (length=5)
    public 'merId' => string '826440148990096' (length=15)
    public 'orderId' => string '2016092805052422' (length=16)
    public 'queryId' => string '201609281709244919698' (length=21)
    public 'respCode' => string '00' (length=2)
    public 'respMsg' => string 'Success!' (length=8)
    public 'settleAmt' => string '1' (length=1)
    public 'settleCurrencyCode' => string '156' (length=3)
    public 'settleDate' => string '0928' (length=4)
    public 'signMethod' => string '01' (length=2)
    public 'traceNo' => string '491969' (length=6)
    public 'traceTime' => string '0928170924' (length=10)
    public 'txnAmt' => string '1' (length=1)
    public 'txnSubType' => string '01' (length=2)
    public 'txnTime' => string '20160928170924' (length=14)
    public 'txnType' => string '01' (length=2)
    public 'version' => string '5.0.0' (length=5)
    public 'signature' => string 'sCicykoKuxa0OoSPasjdklasjdasld'
     * @param array $data
     * @return array|bool
     */
    protected function getTradeData(array $data)
    {
        $retData = [
            'amount'   => $data['txnAmt'] / 100,
            'channel'   => Config::UNIONPAY,
            'order_no'   => $data['orderId'],
            'trade_state'   => Config::TRADE_STATUS_SUCC,
            'transaction_id'   => $data['queryId'],
            'notify_time'   => $data['txnTime'],
            'notify_type'   => Config::TRADE_NOTIFY,// 通知类型为 支付行为
        ];


        return $retData;
    }





    /**
     * 银联，成功返回 ‘success’   失败，返回 ‘fail’
     * @param boolean $flag 每次返回的bool值
     * @param string $msg 错误原因  后期考虑记录日志
     * @return string
     * @author helei
     */
    protected function replyNotify($flag, $msg = '')
    {

        if ($flag) {
            return 'success';
        } else {
            //header('Accept-Patch','true','400');
            return 'fail';
        }
    }

    /**
     * 检查数据 签名是否被篡改
     * @param array $data
     * @return boolean
     * @author helei
     */
    protected function verifySign(array $data)
    {
        // 1. 剔除sign与sign_type参数
        $values = ArrayUtil::removeKeys($data, ['sign', 'sign_type']);
        //  2. 移除数组中的空值
        $values = ArrayUtil::paraFilter($values);
        // 3. 对待签名参数数组排序
        $values = ArrayUtil::arraySort($values);

        $check_sign = \AcpService::validate ($values);
        if(!$check_sign  || $data["respCode"] != "00"){
            return false;
        }else{
            return true;
        }
    }
}